/*
 * 描述： <描述>
 * 修改人： rain
 * 修改时间： 2016年8月10日
 * 项目： rainhy-config
 */
package com.rainhy.config.manager;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.rainhy.config.config.ConfigGroup;
import com.rainhy.config.config.ConfigProperty;
import com.rainhy.config.context.ConfigContext;
import com.rainhy.config.context.ConfigManager;

/**
 * 基础配置属性管理器<br>
 * 
 * @author rain
 * @version [版本号, 2016年8月10日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public abstract class BaseConfigPropertiesManager implements ConfigManager {
    /** 系统日志记录器 */
    protected static final Logger logger = LoggerFactory.getLogger(ConfigContext.class);
    
    /** 配置文件路径 */
    protected String location;
    
    /** 配置文件路径 */
    public String getLocation() {
        return location;
    }
    
    @Override
    public void loadConfig(ConfigContext configContext) {
        List<ConfigContextParse> configContextParseList = loadConfig(configContext, location);
        parseConfigContextParse(configContext, configContextParseList);//解析配置内容
    }
    
    /** 配置文件路径 */
    public void setLocation(String location) {
        this.location = location;
    }
    
    /**
     * 解析本地配置<br/>
     * 
     * @param configContext 配置容器
     * @param configContextParseList 本地配置
     * 
     * @return void [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    private void parseConfigContextParse(
            ConfigContext configContext,
            List<ConfigContextParse> configContextParseList) {
        if (CollectionUtils.isEmpty(configContextParseList)) {
            return;
        }
        
        ///// 迭代循环生成配置属性
        for (ConfigContextParse configContextParse : configContextParseList) {
            ///// 解析日志配置文件中，无配置组的属性集合
            List<ConfigPropertyParse> configPropertyParseList = configContextParse.getConfigs();
            if (CollectionUtils.isNotEmpty(configPropertyParseList)) {
                for (ConfigPropertyParse configPropertyParse : configPropertyParseList) {
                    ///// 将配置属性添加到配置容器中
                    ConfigProperty configProperty = buildConfigProperty(configContext, configContextParse, null, configPropertyParse);
                    configContext.addConfigProperty(configProperty);
                }
            }
            
            //解析配置容器文件中，配置组集合
            List<ConfigGroupParse> configGroups = configContextParse.getConfigGroups();
            parseConfigGroup(configContext, configContextParse, null, configGroups);
        }
    }
    
    /**
     * 
     * 解析组中的配置信息
     *
     * @param configContextParse 本地配置内容
     * @param parentConfigGroupParse 父级本地配置组
     * @param configGroupParseList 本地配置组列表
     * 
     * @return void [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     * @version [版本号, 2016年8月10日]
     * @author rain
     */
    private void parseConfigGroup(
            ConfigContext configContext,
            ConfigContextParse configContextParse,
            ConfigGroupParse parentConfigGroupParse,
            List<ConfigGroupParse> configGroupParseList) {
        if (CollectionUtils.isEmpty(configGroupParseList)) {
            return;
        }
        
        for (ConfigGroupParse configGroupParse : configGroupParseList) {
            ///// 解析配置组
            ConfigGroup configPropertyGroup = buildConfigGroup(configContext, configContextParse, parentConfigGroupParse, configGroupParse);
            configContext.addConfigPropertyGroup(configPropertyGroup);
            
            ///// 解析配置组解析结果中，配置的属性集合
            List<ConfigPropertyParse> configPropertyParseList = configGroupParse.getConfigs();
            if (CollectionUtils.isNotEmpty(configPropertyParseList)) {
                for (ConfigPropertyParse configPropertyParse : configPropertyParseList) {
                    ConfigProperty configProperty = buildConfigProperty(configContext, configContextParse, configGroupParse, configPropertyParse);
                    configContext.addConfigProperty(configProperty);
                }
            }
            
            //迭代解析配置组
            List<ConfigGroupParse> configGroups = configGroupParse.getChilds();
            parseConfigGroup(configContext, configContextParse, configGroupParse, configGroups);
        }
    }
    
    /**
     * 
     * 构建配置属性组<br/>
     * 
     * @param parentConfigGroupParse
     * @param configGroupParse
     * 
     * @return ConfigPropertyGroup [返回类型说明]
     * @exception [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    protected ConfigGroup buildConfigGroup(
            ConfigContext configContext,
            ConfigContextParse configContextParse,
            ConfigGroupParse parentConfigGroupParse,
            ConfigGroupParse configGroupParse) {
        return new ConfigGroupProxy(configContext, parentConfigGroupParse, configGroupParse);
    }
    
    /**
     * 
     * 配置属性
     *
     * @param configContextParse 本地配置内容
     * @param configGroupParse 本地配置组
     * @param configPropertyParse 本地配置属性
     * 
     * @return ConfigProperty [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     * @version [版本号, 2016年8月10日]
     * @author rain
     */
    protected ConfigProperty buildConfigProperty(
            ConfigContext configContext,
            ConfigContextParse configContextParse,
            ConfigGroupParse configGroupParse,
            ConfigPropertyParse configPropertyParse) {
        return new ConfigPropertyProxy(this, configContextParse, configGroupParse, configPropertyParse);
    }
    
    /**
     * 从资源中加载配置内容<br>
     *
     * @param configContext 配置容器
     * @param resource 资源
     * @param configContextParseList 配置内容列表
     * 
     * @return void [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     * @version [版本号, 2016年8月12日]
     * @author rain
     */
    protected abstract List<ConfigContextParse> loadConfig(ConfigContext configContext, String locations);
}
